package com.design.blog.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.design.blog.aop.LogAnno;
import com.design.blog.dao.ArticleBodyMapper;
import com.design.blog.dao.ArticleMapper;
import com.design.blog.dao.UserinfoMapper;
import com.design.blog.model.*;
import com.design.blog.model.vo.*;
import com.design.blog.service.IArticleService;
import com.design.blog.service.ThreadService;
import com.design.blog.utils.JWTUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
import java.util.Optional;

/**
 * @version 1.0
 * @author hxg
 * @date 2022-02-28
 *  服务实现类
 */
@Service
public class ArticleServiceImpl extends ServiceImpl<ArticleMapper, Article> implements IArticleService {

    @Resource
    private ArticleMapper articleMapper;

    @Resource
    private ArticleBodyMapper articleBodyMapper;

    @Resource
    private UserinfoMapper userinfoMapper;

    @Resource
    private ThreadService threadService;

    @Override
    @Cacheable(value = "Article",keyGenerator = "DefaultKeyGenerator",cacheManager = "cacheManager1Day")
    @LogAnno(module = "文章",operator = "获取所有文章")
    public List<Article> getArticles(PageParams params) {
        Page<Article> page = new Page<>(params.getPage(),params.getPageSize());
        LambdaQueryWrapper<Article> wrapper = new LambdaQueryWrapper<>();
        if (params.getCategoryId() != null) {
            wrapper.eq(Article::getCategoryId, params.getCategoryId());
        }
        if (params.getSearchVal() != null) {
            wrapper.like(Article::getTitle, params.getSearchVal());
        }
        List<Article> records = articleMapper.selectPage(page, wrapper).getRecords();
        for (Article article : records) {
            String type = transformTypeId(article.getCategoryId());
            article.setCategoryId(type);
        }
        return records;
    }

    public List<Article> getRecommendArticle() {
        LambdaQueryWrapper<Article> wrapper = new LambdaQueryWrapper<>();
        wrapper.orderByDesc(Article::getViews);
        List<Article> articles = articleMapper.selectList(wrapper);
        for (Article article : articles) {
            String type = transformTypeId(article.getCategoryId());
            article.setCategoryId(type);
        }
        return articles;
    }

    @Cacheable(value = "HotArticle",keyGenerator = "DefaultKeyGenerator",cacheManager = "cacheManager1Day")
    @Override
    public List<Article> getHotArticles() {
        LambdaQueryWrapper<Article> wrapper = new LambdaQueryWrapper<>();
        wrapper.orderByDesc(Article::getViews);
        wrapper.last("limit 5");
        List<Article> articles = articleMapper.selectList(wrapper);
        return articles;
    }

    @Cacheable(value = "NewArticle",keyGenerator = "DefaultKeyGenerator",cacheManager = "cacheManager1Hour")
    @Override
    public List<Article> getNewArticles() {
        LambdaQueryWrapper<Article> wrapper = new LambdaQueryWrapper<>();
        wrapper.orderByDesc(Article::getCreateTime);
        wrapper.last("limit 5");
        List<Article> articles = articleMapper.selectList(wrapper);
        return articles;
    }

    @Override
    public ArticleVO getArticleById(Long id) {
        Article article = articleMapper.selectAllById(id);
        //异步更新阅览量
        threadService.updArticleViews(articleMapper,article);
        ArticleVO articleVO = new ArticleVO();
        BeanUtils.copyProperties(article, articleVO);
        Userinfo userinfo = userinfoMapper.selectById(article.getAuthorId());
        articleVO.setAccount(userinfo.getAccount());
        return articleVO;
    }

    @Override
    @Transactional
    public String publishArticle(String token, ArticleParams param) {
        Map<String, String> tokenMap = JWTUtils.checkToken(token);
        String userId = tokenMap.get("userId");

        String categoryId = transformType(param.getCategory());
        Article article = new Article();
        article.setTitle(param.getTitle());
        article.setSummary(param.getSummary());
        article.setCategoryId(categoryId);
        article.setAuthorId(userId);
        articleMapper.insert(article);

        ArticleBody articleBody = new ArticleBody();
        articleBody.setArticleId(article.getId());

        articleBody.setContent(param.getContent());
        articleBody.setContentHtml(param.getContent());

        articleBodyMapper.insert(articleBody);

        return article.getId();
    }

    @Override
    public List<Article> getSearchArticle(String searchVal) {
        LambdaQueryWrapper<Article> wrapper = new LambdaQueryWrapper<>();
        wrapper.like(Article::getTitle, searchVal);
        return articleMapper.selectList(wrapper);
    }

    @Override
    public Long likeArticle(String id) {
        //todo 单用户只能点赞一次
        Article article = articleMapper.selectById(id);
        LambdaUpdateWrapper<Article> updWrapper = new LambdaUpdateWrapper<>();
        updWrapper.eq(Article::getId, id);
        if (article.getLikes() == null) {
            updWrapper.set(Article::getLikes,1);
            articleMapper.update(article,updWrapper);
        }else {
            updWrapper.set(Article::getLikes, article.getLikes() + 1);
            articleMapper.update(article,updWrapper);
        }
        return article.getLikes();
    }

    @Override
    public PageResult<Article> getAllUseArticle(PageNationParams params) {
        Page<Article> page = new Page<>(params.getCurrentPage(),params.getPageSize());
        LambdaQueryWrapper<Article> queryWrapper = new LambdaQueryWrapper<>();
        if (StringUtils.isNotBlank(params.getQueryString())){
            queryWrapper.like(Article::getTitle,params.getQueryString());
        }
        Page<Article> userPage = articleMapper.selectPage(page, queryWrapper);
        List<Article> records = userPage.getRecords();
        for (Article article : records) {
            article.setCategoryId(transformTypeId(article.getCategoryId()));
        }
        PageResult<Article> pageResult = new PageResult<>();
        pageResult.setList(records);
        pageResult.setTotal(userPage.getTotal());
        return pageResult;
    }

    @Override
    public int chgArticleCategory(String id, String type) {
        return articleMapper.chgCategory(id, transformType(type));
    }

    private String transformType(String type) {
        switch(type){
            case "前端" :
                type="1"; break;
            case "后端" :
                type="2"; break;
            case "数据库" :
                type="3"; break;
            case "数据结构" :
                type="4"; break;
            case "服务器" :
                type="5"; break;
        }
        return type;
    }

    private String transformTypeId(String id) {
        switch(id){
            case "1" :
                id="前端"; break;
            case "2" :
                id="后端"; break;
            case "3" :
                id="数据库"; break;
            case "4" :
                id="数据结构"; break;
            case "5" :
                id="服务器"; break;
        }
        return id;
    }

}
